<?php

declare(strict_types=1);


namespace App\Common\Constants;

use Hyperf\Constants\AbstractConstants;
use ReflectionClass;

abstract class AbstractBaseConstants extends AbstractConstants
{
    /**
     * 常量键值对缓存
     *
     * @var array
     */
    protected static array $constants = [];

    /**
     * 返回所有枚举键值对
     * 若 `$values` 传入数组值，则仅返回 `$values` 范围内的键值对
     *
     * @param array|null $values
     *
     * @return array
     */
    public static function getConstants (array $values = null): array {

        $class = get_called_class();

        if (!array_key_exists($class, static::$constants)) {
            try {
                $constants = (new ReflectionClass($class))->getConstants();
            } catch (\ReflectionException $e) {
                $constants = [];
            }
            static::$constants[$class] = $constants;
        }

        $constants = static::$constants[$class];

        if (is_null($values)) {
            return $constants;
        }

        if (empty($values)) {
            return [];
        }

        return array_filter($constants, function ($item) use ($values) {
            return in_array($item, $values, true);
        });
    }


    /**
     * 返回`$value`范围内的选项列表数组。
     * 若 `$value` 为 `null` 则返回所有。
     *
     * @param array|null $values
     *
     * @return array
     */
    public static function getOptions (array $values = null): array
    {
        return array_map(function ($key, $value){
            return array('key' => $key, 'label'=>static::getMessage($value), 'value' => $value,);
        },array_keys(static::getConstants($values)),static::getConstants($values));
    }

    /**
     * 返回包含所有枚举值的数组。
     *
     * @return array
     */
    public static function getValues (): array
    {
        return array_values(static::getConstants());
    }
}